web-aware contexts中的其他范围
有几个范围仅在web-aware应用程序上下文中可用:
- request - 每个HTTP请求创建新的bean实例
- session - 每个HTTP会话创建新的bean实例
- application - 每个
ServletContext
创建一个新的bean实例 - globalSession - 在Portlet环境中为每个全局会话创建新的bean实例(在Servlet环境中,全局会话范围等于会话范围)
- websocket - 根据WebSocket会话创建新的bean实例
在Spring Web MVC中声明和访问Web范围的bean不需要额外的设置。
XML配置
|
|
Java配置(Spring 4.3之前)
|
|
Java配置(Spring 4.3之后)
|
|
Annotation-Driven Components
|
|
prototype-scope 原型范围
原型范围的bean不是在Spring容器启动时预先创建的。 相反,每次将检索此bean的请求发送到容器时,将创建一个新实例。 对于有状态对象,建议使用此作用域,因为其状态不会被其他组件共享。
为了定义一个原型范围的bean,我们需要添加@Scope
注释,指定我们想要的范围类型。
给出以下MyBean类:
|
|
我们定义一个bean定义,将其范围说明为原型:
|
|
为了看看它是如何工作的,我们从Spring容器检索bean,并为其属性字段设置不同的值。 接下来,我们将再次从容器中检索bean并查找其值:
|
|
看看下面的结果,我们可以看到如何在每个bean请求上创建一个新的实例:
|
|
一个常见的错误就是假设每个调用或每个线程重建bean,但情况并非如此。 相反,创建一个实例PER INJECTION(或从上下文检索)。 如果一个Prototype作用域bean只被注入到一个单独的bean中,那么只有该Prototype作用域bean的一个实例。
Spring不管理原型bean的完整生命周期:容器实例化,配置,修饰和装配一个原型对象,将其传递给客户端,然后对原型实例没有进一步的了解。
singleton scope 单例范围
如果bean是使用singleton scope定义的,那么只有一个对象实例在Spring容器中初始化。 对此bean的所有请求都将返回相同的共享实例。 这是定义bean时的默认范围。
给出以下MyBean类:
|
|
我们可以使用@Bean
注释定义一个单例bean:
|
|
以下示例从Spring上下文中检索同一个bean两次:
|
|
当记录singletonBean2属性时,将显示消息“changed property”,因为我们刚刚检索了相同的共享实例。
由于实例在不同组件之间共享,因此建议为无状态对象定义单例范围。
Lazy singleton beans 延迟单例bean
默认情况下,singleton bean是预先实例化的。 因此,将在创建Spring容器时创建共享对象实例。 如果我们启动应用程序,将显示“Initializing singleton bean …”消息。
如果我们不希望bean被实例化,我们可以添加@Lazy
注释到bean定义。 这将阻止在第一次请求之前创建bean。
|
|
现在,如果我们启动Spring容器,将不会出现“Initializing lazy singleton bean …”消息。 在第一次请求bean之前,不会创建该bean:
|
|
如果我们在定义了单例和延迟单例bean的情况下运行应用程序,它将产生以下消息:
|
|